package top.pcat.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;
import top.pcat.config.ZookeeperConfig;

@Slf4j
public class ZookeeperUtil {
    private final ZookeeperConfig zookeeperConfig;
    private final String host;
    private volatile CuratorFramework client = null;

    /**
     * 构造 Zookeeper
     * @param zookeeperConfig zookeeper配置信息
     * @param host 主机host
     */
    public ZookeeperUtil(ZookeeperConfig zookeeperConfig, String host) {
        this.zookeeperConfig = zookeeperConfig;
        this.host = host;
        if (client == null) {
            synchronized (ZookeeperUtil.class) {
                if (client == null) {
                    this.client = CuratorFrameworkFactory.builder()
                            .connectString(zookeeperConfig.getConnectString())
                            .sessionTimeoutMs(zookeeperConfig.getSessionTimeoutMs())
                            .connectionTimeoutMs(zookeeperConfig.getConnectionTimeoutMs())
                            .retryPolicy(new ExponentialBackoffRetry(zookeeperConfig.getBaseSleepTimeMs(), zookeeperConfig.getMaxRetries()))
                            .build();
                    client.start();
                }
            }
        }
    }

    /**
     * 注册服务器
     * @return zookeeper注册是否成功
     */
    public boolean register() {
        try {
            client.create()
                .creatingParentsIfNeeded()
                .withMode(CreateMode.EPHEMERAL)
                .forPath(zookeeperConfig.getDevicePath() + "/" + host);
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }

    }

    public void remove(){
        try {
            client.delete().deletingChildrenIfNeeded().forPath(zookeeperConfig.getDevicePath() + "/" + host);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


}
